import json
import os
import threading
from datetime import datetime
from tkinter import ttk, Label, scrolledtext, Button, Entry

import pandas as pd
import requests
import tkinter as tk

from util.comm.AsyncTask import AsyncTask
from util.comm.cmd_util import wrap_with_try_except
from util.comm.msg_util import msg
from util.comm.path import getConfigPath
from util.window.config_window.config_button import create_config_button


class WinPcNacos():
    def __init__(self):
        super().__init__()

    def frame(self, tab):
        self.tab = tab

        self.elements = []

        self.config_path = getConfigPath()
        self.button = create_config_button(self, True)

        self.menu = ttk.Frame(self.tab)
        self.menu.pack()
        self.elements.append(self.menu)

        config_path = getConfigPath()
        with open(config_path, 'r', encoding='utf-8') as f:
            config = json.load(f)
        self.menuFrame(self.menu, config)

    def menuFrame(self, tab, config):
        self.menu = tab
        content = config
        params = content["params"]
        # 增加输入框
        map = {}
        if isinstance(params, list):
            row = 1
            for index, param in enumerate(params):
                title = param['field_title']
                field = param['field']
                w = param['width']
                h = param['height']

                # 标题
                self.label = Label(self.menu, text=title)
                self.label.grid(row=row, column=0, padx=5, pady=5)

                self.Entry = Entry(self.menu, width=w)
                self.Entry.grid(row=row, column=1, padx=5, pady=5)
                self.Entry.insert(0, param["field_value"])

                map[field] = self.Entry

                row += 1

                new_row = tk.Frame(self.menu)
                new_row.grid(row=row, column=0, sticky='news')

        # 增加按钮
        button = content["button"]

        self.button = Button(self.menu, text=button, command=lambda n=content["name"], t=tab, c=content, m=map: self.print_entry_sync(n, t, c, m), width=12)
        self.button.grid(row=row, column=1, padx=36, pady=5)

    def print_entry_sync(self, n, t, c, m):
        flag = "sync_flag_%s" % n
        if hasattr(self, flag) and getattr(self, flag) == '1':
            msg('正在处理,请勿重复操作')
            return
        setattr(self, flag, '1')
        wrap_print_entry = wrap_with_try_except(self.print_entry)
        AsyncTask(threading.Thread(target=wrap_print_entry, args=(t, c, m,)),
                  lambda n=n: self.reset_sync(n)).execute_async()

    def reset_sync(self, n):
        flag = "sync_flag_%s" % n
        setattr(self, flag, '0')

    def print_entry(self, t, c, m):
        if hasattr(t, 'label_out'):
            t.label_out.destroy()
        map = {}
        for key, value in m.items():
            v = ""
            try:
                v = value.get()
            except:
                pass
            map[key] = v
        url = map['url']
        namespace = map['namespace']
        save_path = map['save_path']
        # 获取服务列表
        servers = get_servers(url, namespace)
        # 创建一个空列表来存储服务器信息
        server_info = []
        # 遍历每个服务器并获取其信息
        for server in servers:
            server_details = get_server_info(url, namespace, server)
            server_info.extend(server_details)
        # 从服务器信息列表创建DataFrame
        df = pd.DataFrame(server_info, columns=["服务名", "版本", "描述", "IP", "端口"])
        # 将DataFrame保存为Excel文件
        df.to_excel(f"{save_path}", index=False)
        # 打开excel文件
        os.startfile(f"{save_path}")

        createLabelOut(t, "结果：已输出【%s】" % datetime.now())


def createLabelOut(tab, message):
    if len(message) > 100:
        message = message[:45] + '...' + message[-45:-1]
    tab.label_out = Label(tab, text=message)
    tab.label_out.grid(column=1)

def get_servers(ip, namespaceId):
    url = f"{ip}/nacos/v1/ns/service/list"
    params = {
        "pageNo": 0,
        "pageSize": 1000,
        "namespaceId": f"{namespaceId}"
    }
    response = requests.get(url, params=params)

    if response.status_code == 200:
        data = response.json()
        doms = data["doms"]
        return doms
    else:
        msg("请求异常：", response.status_code)
        return 999

def get_server_info(ip, namespaceId, servername):
    url = f"{ip}/nacos/v1/ns/instance/list"
    params = {
        "serviceName": f"{servername}",
        "namespaceId": f"{namespaceId}"
    }
    response = requests.get(url, params=params)

    if response.status_code == 200:
        data = response.json()
        hosts = data["hosts"]
        server_info = []

        for host in hosts:
            server_details = {
                "服务名": host["serviceName"].split('@')[-1],
                "IP": host["ip"],
                "端口": host["port"],
                "版本": host.get('metadata', {}).get('version', ''),
                "描述": host.get('metadata', {}).get('description', ''),
            }
            server_info.append(server_details)
        return server_info
    else:
        msg("请求异常：", response.status_code)
        return []



